﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using MySql.Data;
using MySql.Data.MySqlClient;

namespace DataLayer {
    public class DAO<T> {//: IDAOCrud<T> {

        private void initializeTypes() {
            mySqlTypes = new Dictionary<string, string>();

            mySqlTypes.Add("int", "integer");
            mySqlTypes.Add("string", "varchar(100)");
            mySqlTypes.Add("double", "number(6, 2)");
        }

        public DAO(string connectionString) {
            initializeTypes();
            tableName = typeof(T).Name + "s";
            connection = new MySqlConnection(connectionString);
            this.properties = new List<PropertyInfo>(typeof(T).GetProperties());
        }

        public DAO(string tableName, string connectionString) {
            initializeTypes();
            this.tableName = tableName;
            connection = new MySqlConnection(connectionString);
            this.properties = new List<PropertyInfo>(typeof(T).GetProperties());
        }

        ~DAO() {
            if (connection.State.ToString() == "Open")
                connection.Close();
        }

        public bool tableExists() {
            return false;
        }

        public void createTable() {
            if (tableExists())
                return;

            string query = "CREATE TABLE(";
            foreach (PropertyInfo p in properties)
                query += p.Name + ", ";
            query = query.Substring(0, query.Length - 2);
            query += ");";

            Console.WriteLine(query);

            try { 
                connection.Open();

                MySqlCommand comm = new MySqlCommand(query, connection);
                comm.ExecuteScalar();
            } catch(Exception general_ex) {
                throw general_ex;
            } finally {
                connection.Close();
            }
        }

        public long create(T entity) {
            // forming query
            try {
                connection.Open();
                string query = "INSERT INTO " + tableName + " (";
                foreach (PropertyInfo p in properties)
                    query += p.Name + ", ";
                query = query.Substring(0, query.Length - 2);
                query += ") VALUES (";
                foreach (PropertyInfo p in typeof(T).GetProperties()) {
                    string current;
                    //if(p.PropertyType == typeof(string))
                        current = "\"" + p.GetMethod.Invoke(entity, null).ToString() + "\"" + ", ";
                    //else
                      //  current = p.GetMethod.Invoke(entity, null).ToString() + ", ";
                    query += (current == ", " || current == "\"\", ") ? "NULL, " :  current;
                }
                query = query.Substring(0, query.Length - 2);
                query += ");";

                Console.WriteLine(query);

                MySqlCommand comm = new MySqlCommand(query, connection);
                comm.ExecuteScalar();
            } catch(MySqlException mysql_ex) {
                throw mysql_ex;
            } catch (Exception general_ex) {
                throw new DataLayerException("DAO : Insertion failed.");
            } finally {
                connection.Close();
            }

            return 0;
        }

        public List<T> getAll() {



            return null;
        }

        public void createTable() { 
            
        }

        /*public T read(T entity);        // SELECT FROM WHERE ..
        public T update(T entity);     // UPDATE
        public void delete(T entity);  // DELETE
        public T getById(int id);       // SELECT .. WHRE ID=
        public List<T> getByExample(string name, string value);  // SELECT .. WHERE name=value*/

        private List<PropertyInfo> properties;
        private string tableName;
        private MySqlConnection connection;
        private static Dictionary<string, string> mySqlTypes;
    }
}
